package com.bicntech.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bicntech.common.exception.ServiceException;
import com.bicntech.common.helper.LoginHelper;
import com.bicntech.common.utils.ObjectUtil;
import com.bicntech.system.dto.InfieldBasicDataQueryDTO;
import com.bicntech.system.dto.InfieldInspectAddDTO;
import com.bicntech.system.dto.InfieldRefuelingVolumeDTO;
import com.bicntech.system.dto.InfieldVehicleEquipmentInspectDTO;
import com.bicntech.system.entity.InfieldBasicData;
import com.bicntech.system.entity.InfieldVehicleEquipmentInspect;
import com.bicntech.system.service.InfieldBasicDataService;
import com.bicntech.system.service.InfieldVehicleEquipmentInspectService;
import com.bicntech.system.mapper.InfieldVehicleEquipmentInspectMapper;
import com.bicntech.system.service.VehicleRefuelingStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author casc1
 * @description 针对表【infield_vehicle_equipment_inspect(机务维修记录--内场)】的数据库操作Service实现
 * @createDate 2024-03-07 21:47:23
 */
@Service
@Slf4j
public class InfieldVehicleEquipmentInspectServiceImpl extends ServiceImpl<InfieldVehicleEquipmentInspectMapper, InfieldVehicleEquipmentInspect>
        implements InfieldVehicleEquipmentInspectService {

    @Resource
    private InfieldBasicDataService infieldBasicDataService;

    @Resource
    private VehicleRefuelingStatisticsService refuelingStatisticsService;


    @Override
    public IPage<InfieldVehicleEquipmentInspectDTO> listInfieldVehicleEquipmentInspectsByPage(IPage<InfieldVehicleEquipmentInspect> iPage, InfieldBasicDataQueryDTO queryDTO) {
        return super.page(iPage, queryWrapper(queryDTO)).convert(ObjectUtil.transform(InfieldVehicleEquipmentInspectDTO.class));
    }

    @Override
    public List<InfieldVehicleEquipmentInspectDTO> listInfieldVehicleEquipmentInspects(InfieldVehicleEquipmentInspectDTO infieldVehicleEquipmentInspectDTO) {
        QueryWrapper<InfieldVehicleEquipmentInspect> queryWrapper = new QueryWrapper<InfieldVehicleEquipmentInspect>();
        return ObjectUtil.deepCopyList(super.list(queryWrapper),InfieldVehicleEquipmentInspectDTO.class);
    }



    @Override
    public InfieldVehicleEquipmentInspectDTO getInfieldVehicleEquipmentInspectById(Long id) {
        InfieldVehicleEquipmentInspectDTO infieldVehicleEquipmentInspectDTO = ObjectUtil.entityToModel(super.getById(id), InfieldVehicleEquipmentInspectDTO.class);
        return infieldVehicleEquipmentInspectDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addInfieldVehicleEquipmentInspect(InfieldInspectAddDTO addDTO) {
        LocalDate inspectDate = addDTO.getInspectDate().toLocalDate();
        if (checkByWagonNumber(addDTO.getWagonNumber(), inspectDate)) {
            throw new ServiceException("添加失败！车牌号：" + addDTO.getWagonNumber() + "在" + inspectDate + "已完成检查");
        }
        InfieldVehicleEquipmentInspect infieldVehicleEquipmentInspect = ObjectUtil.entityToModel(addDTO, InfieldVehicleEquipmentInspect.class);
        //生成code
        String code;
        do {
            code = "N" + LocalDate.now().toString().replace("-", "") + RandomUtil.randomNumbers(6);
        } while (checkCode(code));
        infieldVehicleEquipmentInspect.setCode(code);
        infieldVehicleEquipmentInspect.setSignatureOfInspector(LoginHelper.getUsername());
        infieldVehicleEquipmentInspect.setSignatureOfInspectorId(LoginHelper.getUserId().toString());

        if (!"0".equals(infieldVehicleEquipmentInspect.getRefuelingVolume())) {
            infieldVehicleEquipmentInspect.setSignatureOfInspector(LoginHelper.getUsername());
            infieldVehicleEquipmentInspect.setSignatureOfInspectorId(LoginHelper.getUserId().toString());
        }
        if (super.save(infieldVehicleEquipmentInspect)) {
            log.info("插入infieldVehicleEquipmentInspect成功,id为{}", infieldVehicleEquipmentInspect.getId());
            return infieldVehicleEquipmentInspect.getId();
        }
        throw new ServiceException("添加失败");
    }


    @Override
    public Boolean checkByWagonNumber(String wagonNumber, LocalDate localDate) {
        return lambdaQuery()
                .eq(InfieldVehicleEquipmentInspect::getWagonNumber, wagonNumber)
                .eq(InfieldVehicleEquipmentInspect::getInspectDate, localDate.atTime(LocalTime.MIN))
                .count() > 0;
    }

    @Override
    public Long deleteInfieldVehicleEquipmentInspectById(Long id) {
        InfieldVehicleEquipmentInspect infieldVehicleEquipmentInspect = Optional.ofNullable(super.getById(id))
                .filter(ObjectUtil::notEmpty)
                .orElseThrow(() -> new ServiceException("操作失败,检查单不存在"));
        if (super.removeById(id)) {
            return id;
        }
        throw new ServiceException("删除失败,检查单不存在");
    }

    @Override
    public Long updateInfieldVehicleEquipmentInspect(InfieldVehicleEquipmentInspectDTO infieldVehicleEquipmentInspectDTO) {
        InfieldVehicleEquipmentInspect infieldVehicleEquipmentInspect = ObjectUtil.entityToModel(infieldVehicleEquipmentInspectDTO, InfieldVehicleEquipmentInspect.class);
        if (super.updateById(infieldVehicleEquipmentInspect)) {
            return infieldVehicleEquipmentInspect.getId();
        } else {
            throw new ServiceException("更新失败[id=" + infieldVehicleEquipmentInspect.getId() + "]");
        }
    }

    @Override
    public Long getInfieldSpecialVehicleCount() {
        LocalDateTime startDateTime = LocalDate.now().atStartOfDay();
        LocalDateTime endDateTime = startDateTime.plusDays(1);
        return Optional.ofNullable(infieldBasicDataService.getIsSpecialVehicle())
                .filter(CollUtil::isNotEmpty)
                .map(t -> t.stream().map(InfieldBasicData::getId).collect(Collectors.toList()))
                .map(re -> super.lambdaQuery()
                        .in(InfieldVehicleEquipmentInspect::getType, re)
                        .ge(InfieldVehicleEquipmentInspect::getInspectDate, startDateTime)
                        .lt(InfieldVehicleEquipmentInspect::getInspectDate, endDateTime)
                        .count())
                .orElse(0L);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateInspect(InfieldRefuelingVolumeDTO infieldRefuelingVolumeDTO) {
        Long id = infieldRefuelingVolumeDTO.getId();
        BigDecimal updateRefuelingVolume = infieldRefuelingVolumeDTO.getRefuelingVolume();

        InfieldVehicleEquipmentInspect vehicleEquipmentInspect = super.getById(id);
        BigDecimal refuelingVolume = vehicleEquipmentInspect.getRefuelingVolume();
        vehicleEquipmentInspect.setRefuelingVolume(updateRefuelingVolume);

        if (super.updateById(vehicleEquipmentInspect)) {
            refuelingStatisticsService.addRefueling(vehicleEquipmentInspect.getWagonNumber(),
                    vehicleEquipmentInspect.getInspectDate(), updateRefuelingVolume.subtract(refuelingVolume));
            return vehicleEquipmentInspect.getId();
        } else {
            throw new ServiceException("更新失败[id=" + vehicleEquipmentInspect.getId() + "]");
        }
    }


    public boolean checkExistence(InfieldInspectAddDTO request) {
        return lambdaQuery()
                .eq(InfieldVehicleEquipmentInspect::getInspectDate, request.getInspectDate())
                .eq(InfieldVehicleEquipmentInspect::getWagonNumber, request.getWagonNumber())
                .count() != 0;
    }

    public boolean checkCode(String code) {
        return lambdaQuery()
                .eq(InfieldVehicleEquipmentInspect::getCode, code)
                .count() != 0;
    }


    private LambdaQueryWrapper<InfieldVehicleEquipmentInspect> queryWrapper(InfieldBasicDataQueryDTO queryDTO) {
        String mpUserid = null;
        if (Boolean.TRUE.equals(queryDTO.getIsMe())) {
            mpUserid = LoginHelper.getUserId().toString();
        }
        LocalDateTime startDateView = null;
        LocalDateTime endDateView = null;

        if (ObjectUtil.notEmpty(queryDTO.getDateView())) {
            startDateView = queryDTO.getDateView().atStartOfDay();
            endDateView = startDateView.plusDays(1);
        }
        return new LambdaQueryWrapper<InfieldVehicleEquipmentInspect>()
                .like(ObjectUtil.notEmpty(queryDTO.getWagonNumber()), InfieldVehicleEquipmentInspect::getWagonNumber, queryDTO.getWagonNumber())
                .like(ObjectUtil.notEmpty(queryDTO.getApplicableModels()), InfieldVehicleEquipmentInspect::getApplicableModels, queryDTO.getApplicableModels())
                .ge(ObjectUtil.notEmpty(startDateView), InfieldVehicleEquipmentInspect::getInspectDate, startDateView)
                .lt(ObjectUtil.notEmpty(endDateView), InfieldVehicleEquipmentInspect::getInspectDate, endDateView)
                .eq(StrUtil.isNotBlank(mpUserid), InfieldVehicleEquipmentInspect::getSignatureOfInspectorId, mpUserid)
                .ge(ObjectUtil.notEmpty(queryDTO.getStartTime()), InfieldVehicleEquipmentInspect::getInspectDate, queryDTO.getStartTime())
                .lt(ObjectUtil.notEmpty(queryDTO.getEndTime()), InfieldVehicleEquipmentInspect::getInspectDate, queryDTO.getEndTime())
                .orderByDesc(InfieldVehicleEquipmentInspect::getCreateTime);
    }


}




